/*
 * Created on May 2, 2005
 *
 */
package littlecyberwar.ui.overlay;

import java.awt.*;
import java.awt.geom.Area;
import littlecyberwar.util.*;
import littlecyberwar.ui.*;

/**
 * This class handles all of the Element's overlay related issues
 * The life of the delegate is only when a unit is selected
 * 
 * @author Milton  Soong
 *
 */
public class OverlayDelegate {

	/**
	 * instance variable
	 */
	private int state;	// this holds modeID:State info
	
	/**
	 * State definitions
	 * there's a state for each mode
	 * (note there is no mode on state, since for performance reason only selected element will EVER have
	 * mode on called
	 */
	private final static int ST_INIT=1;				// init state
	private final static int ST_ELEMENT_SELECTED=2;	// element selected
	private final static int ST_ELEMENT_SELECTED_OVERLAY_ON=3;	// element selected & overlay on 
		 
	private OverlayInstance instance;	// the overlay instance associated with the element
	private Shape runtime;		// runtime
//	private Element el;			// the associated element
	
	/**
	 * This is the Area occupied by the last visible runtime.
	 * Until this is called, it is not cleared. Once it's called, then it's gone
	 */
	private Area clearArea;
	
	public OverlayDelegate() {
		// TODO Auto-generated constructor stub
	}

	protected OverlayDelegate(Element elIn, OverlayInstance instanceIn) {
		super();
		// TODO Auto-generated constructor stub
		state = ST_INIT;
		instance = instanceIn;
//		el = elIn;
		clearArea = null;
	}
	
	/**
	 * 
	 * @param currEl 
	 * @param overlayId if the id == null, then return a defaultOverlay 
	 * @return
	 */
	public static OverlayDelegate getOverlayDelegateInstance(Element currEl, String overlayId) {
		OverlayDelegate ovd = null;
		if ( overlayId != null ) {
			String instanceKey = Util.getElementHashLookupOverlayInstance(overlayId);
			OverlayInstance ovi = (OverlayInstance)currEl.getNewProps(instanceKey);
			ovd = new OverlayDelegate(currEl, ovi);
			
		} else {
			ovd = new OverlayDelegateDefault();
		}
		return ( ovd );
	}

	/**
	 * The associated element has been selected by the user
	 * If there are no current OverlayRuntime, then need to calculate it
	 * If there are current Overlayruntime (haven't moved since last time, then use it
	 *
	 */
	public void elementSelected() {
		
		switch ( state ){
			case ST_INIT:
				state = ST_ELEMENT_SELECTED;
				break;
				
			case ST_ELEMENT_SELECTED:
			case ST_ELEMENT_SELECTED_OVERLAY_ON:
				break;
				
			default:
				Debug.out("Invalid State");
		}
		return;
	}
	
	/**
	 * unit is no longer selected 
	 */
	public void elementDeselected() {
		switch ( state ){
			case ST_INIT:
			case ST_ELEMENT_SELECTED:
				break;				
			
			case ST_ELEMENT_SELECTED_OVERLAY_ON:
				clearArea = new Area(runtime);
				break;
				
			default:
				Debug.out("Invalid State");
		}
		state = ST_INIT;
		return;
	}
	
	/**
	 * unit selected AND the overlay is on
	 *
	 */
	public void elementSelectedWithOverlay(Element el) {
		switch ( state ){
			case ST_INIT:
			case ST_ELEMENT_SELECTED:
				state = ST_ELEMENT_SELECTED_OVERLAY_ON;
				if ( runtime == null) {
					runtime = instance.getRuntime(el);
				}
				clearArea = new Area(runtime);
				break;
				
	
			case ST_ELEMENT_SELECTED_OVERLAY_ON:
				break;
				
			default:
				Debug.out("unitMoved Invalid State");
	}
	return;		
		
	}

	/**
	 * 
	 * @param tempShape the shape of the current selected unit interim shape
	 */
	public void unitMoved(Shape tempShape) {
		switch ( state ){
			case ST_INIT:
			case ST_ELEMENT_SELECTED:
				// if there was a runtime associated, it is invalid now
				runtime = null;
				break;
				
	
			case ST_ELEMENT_SELECTED_OVERLAY_ON:
				// need to calculate the new runtime for this element
				runtime = tempShape;
				Area newPosition = new Area(runtime);
				if ( clearArea != null ){
					clearArea.add(newPosition);
				} else {
					clearArea = newPosition;
				}
				break;
				
			default:
				Debug.out("unitMoved Invalid State");
		}
		return;		
	}
	/**
	 * Paint delegate method
	 * All visible OverlayRuntime associated with this element is painted
	 * 1) if runtime is not null, then proceed
	 * 2) the runtime should have the latest transformed Shape. get it and paint it
	 */
	public void paintStuff(Graphics2D g2) {
		if ( runtime != null ){
			  g2.setComposite(this.instance.getAlphaComposit());
			  g2.setColor(this.instance.getColor());
			  g2.fill(runtime);
		}
	}
	/**
	 * @return Returns the clearArea.
	 */
	public Rectangle getClearArea() {
		Area temp = clearArea;
		clearArea = null;
		Rectangle val = null;
		if ( temp != null ){
			val = temp.getBounds();
		}
		return ( val );
	}
	
}
